Tutorial Study Image

C++ 重载


2023年6月2日, Learn eTutorial
936

在本教程中,我们将通过示例学习 C++ 中不同类型的重载。C++ 中的重载主要有两种类型:函数重载和运算符重载。现在让我们详细学习 C++ 重载。

在 C++ 中,我们主要可以重载

  • 方法,
  • 构造函数
  • 索引属性

这是因为这些成员只包含参数。

C++ 中重载的两种类型

C++ 中主要有两种重载类型

  • 函数重载
  • 运算符重载
C++ Overloading

C++ 函数重载

在 C++ 中,函数重载定义为具有相同名称但参数不同的两个或多个函数的处理过程。重载函数主要是通过使用不同类型的参数或使用不同数量的参数来重新定义它。只有通过这些区别,编译器才能区分这些函数。

函数重载的好处是可以通过消除对相同操作的多个名称的需求来提高程序的可读性。

例如,
这里你可以看到相同的名称但不同的参数


int test() { }
int test(int a) { }
float test(double a) { }
int test(int a, double b) { }
 

在这种情况下,所有四个函数都已重载。

请注意,这四个函数的返回类型不相同。重载函数可以具有不同的返回类型,也可以没有,但它们必须具有不同的参数。

例如,
// 错误代码

int test(int a) { }

double test(int b){ }

在这种情况下,两个函数都具有相同的名称、类型和参数数量。因此,编译器将生成一个错误。

示例 1:主要使用不同类型的参数的 C++ 函数重载

编写一个程序来计算绝对值,它适用于 int 和 float 两种类型。


#include <iostream>
using namespace std;

// A float-type parameter in a function
float absolute(float var){
    if (var < 0.0)
        var = -var;
    return var;
}

// A function with an int-type parameter
int absolute(int var) {
     if (var < 0)
         var = -var;
    return var;
}

int main() {
    
    // call function with int type  parameter
    cout << "Absolute value of -7 = " << absolute(-7) << endl;

    // call function with float type parameter
    cout << "Absolute value of 7.7 = " << absolute(7.7f) << endl;
    return 0;
}

 

输出


Absolute value of -7 = 7
Absolute value of 7.7 = 7.7

此图显示 absolute() 函数正在使用重载。

C++ Overloading

在上面的程序中,absolute() 函数被重载。根据函数调用期间传递的参数类型,调用相应的函数。

该程序显示了使用不同数量参数的 C++ 重载


#include <iostream>
using namespace std;

// function with 2 parameters
void display(int var1, double var2) {
    cout << "Integer number: " << var1;
    cout << " and double number: " << var2 << endl;
}

// function with double type single parameter
void display(double var) {
    cout << "Double number: " << var << endl;
}

// function with int type single parameter
void display(int var) {
    cout << "Integer number: " << var << endl;
}

int main() {

    int a = 7;
    double b = 7.7;

    // calling a function with an int type parameter
    display(a);

    // calling a function with an double type parameter 
    display(b);

    // using two parameters to call a function
    display(a, b);

    return 0;
}

 

输出


Integer number: 7
Double number: 7.7
Integer number: 7 and double number: 7.7

在这种情况下,display() 函数被调用了三次,带有不同的参数。根据传递的参数数量和类型,调用相应的 display() 函数。

该图显示了 display() 函数的重载工作原理

C++ Overloading

所有这些函数都具有相同的返回类型,但这并非函数重载的常态。

要记住的一点: C++ 中的许多标准库函数都是重载的。例如,sqrt() 函数可以接受 double、float、int 等参数。这是因为 C++ 中的 sqrt() 函数是重载的。

二义性与函数重载

当编译器无法确定应该调用哪个重载函数时,就会发生函数重载。

当编译器显示歧义错误时,程序将不会执行。

函数重载的主要原因是什么?

C++ Overloading

类型转换

类型转换的示例程序


#include<iostream>  
using namespace std;  
void fun(int);  
void fun(float);  
void fun(int i)  
{  
    std::cout << "Value of i is : " <<i<< std::endl;  
}  
void fun(float j)  
{  
    std::cout << "Value of j is : " <<j<< std::endl;  
}  
int main()  
{  
    fun(12);  
    fun(1.2);  
    return 0;  
}  

 

上述示例中指出的错误是“对重载的 'fun(double)' 的调用存在歧义”。第一个函数将调用 fun(10)。根据我们的预测,fun(1.2) 调用第二个函数。然而,这不适用于任何函数,因为在 C++ 中,所有浮点常量都被视为 double 而不是 float。如果我们将 float 更改为 double,程序就可以工作。因此,这是一个从 float 到 double 的类型转换。

带有默认参数的函数

带有默认参数的函数的示例程序


#include<iostream>  
using namespace std;  
void fun(int);  
void fun(int,int);  
void fun(int i)  
{  
    std::cout << "Value of i is : " <<i<< std::endl;  
}  
void fun(int a,int b=9)  
{  
    std::cout << "Value of a is : " <<a<< std::endl;  
    std::cout << "Value of b is : " <<b<< std::endl;  
}  
int main()  
{  
    fun(12);  
   
    return 0;  
}  

 

前面的示例演示了一个错误:“对重载的 'fun(int)' 的调用存在歧义。” fun(int a, int b=9) 函数可以通过两种方式调用:一种带一个参数,fun(12),另一种带两个参数,fun(12) (4,5)。带一个参数时,调用 fun(int i) 函数。因此,编译器无法在 fun(int I) 和 fun(int a, int b=9) 之间进行选择。

带引用传递的函数

带引用传递的函数的示例程序


#include <iostream> 
using namespace std;  
void fun(int);  
void fun(int &);   
int main()  
{  
int a=10;  
fun(a); // error, which f()?  
return 0;  
}  
void fun(int x)  
{  
std::cout << "Value of x is : " <<x<< std::endl;  
}  
void fun(int &b)  
{  
std::cout << "Value of b is : " <<b<< std::endl;  
}  

 

前面的示例包含一个错误:“对重载的 'fun(int&)' 的调用存在歧义。”第一个函数接受一个整数参数,而第二个函数接受一个引用参数作为参数。在这种情况下,编译器不知道用户需要哪个函数,因为 fun(int) 和 fun(int) (int &) 之间没有语法上的区别。

C++ 中的运算符重载

运算符重载是一种编译时多态,其中运算符将被重载,以便为用户定义的数据类型赋予特殊含义。C++ 中可用的大多数运算符都通过运算符重载进行重载或重新定义。它用于对用户定义的数据类型执行操作。C++ 允许您添加适用于内置数据类型的用户定义数据类型变量。

运算符重载的好处是它允许您对相同的操作数执行多个操作。

有一些运算符不能重载,它们是

  • 作用域运算符 (::)
  • Sizeof
  • 成员选择器 (.)
  • 成员指针选择器 (*)
  • 三元运算符 (?:)

运算符重载的语法


 return_type class_name  : : operator op(argument_list)  
 {  
      // is the body of the function.  
 }  
 

其中 return_type 是函数返回值的类型。

class_name 是类的名称。

运算符 op 是一个运算符函数,其中 op 是重载的运算符,operator 是关键字。

运算符重载规则

  • 只能重载已有的运算符;不能重载新运算符。
  • 重载运算符中至少有一个操作数是用户定义的数据类型。
  • 友元函数不能用于重载特定运算符。而成员函数可以用于重载这些运算符。
  • 当一元运算符通过成员函数重载时,它们不带显式参数;但当通过友元函数重载时,它们带一个参数。
  • 当二元运算符通过成员函数重载时,它们带一个显式参数;当它们通过友元函数重载时,它们带两个显式参数。

让我们看一个 C++ 运算符重载的简单示例。在此示例中,定义了 void operator ++ () 运算符函数(在 Test 类内部)。

一个用于重载一元运算符 ++ 的程序。


#include <iostream>   
using namespace std;    
class Test    
{    
   private:    
      int num;    
   public:    
       Test(): num(8){}    
       void operator ++()         {     
          num = num+2;     
       }    
       void Print() {     
           cout<<"The Count will be: "<<num;     
       }    
};    
int main()    
{    
    Test tt;    
    ++tt;  // calling of a function "void operator ++()"    
    tt.Print();    
    return 0;    
}    

 

输出


The Count will be:10

一个用于重载二元运算符的程序


#include <iostream>  
using namespace std;  
class A  
{  
    
    int x;  
      public:  
      A(){}  
    A(int i)  
    {  
       x=i;  
    }  
    void operator+(A);  
    void display();  
};  
  
void A :: operator+(A a)  
{  
     
    int m = x+a.x;  
    cout<<"so the result of the addition of two objects will be : "<<m;  
  
}  
int main()  
{  
    A a1(5);  
    A a2(4);  
    a1+a2;  
    return 0;  
}  

 

输出


so the result of the addition of two objects will be :9